import BaseDrag from "../../Base/BaseDrag";
import { EBundleType, ESkeNameType, EViewType } from "../../Common/Enum";
import { TalkModule } from "../../Common/TalkModule";
import { IBaseSkeData, IViewData } from "../../Interface/IMessage";
import { ELayerType, SceneGame } from "../../SceneGame";
import AppService from "../../Service/AppService";
import AudioManager from "../../Util/AudioManager";
import GameUtil from "../../Util/GameUtil";
import ItemDrag, { EDragType } from "./ItemDrag";

const { ccclass, property } = cc._decorator;

const VIEW_DATA: IViewData = {
    name: 'LayerStory1',
    type: EViewType.Layer,
    bundle: EBundleType.Story,
    zIndex: 100,
};

@ccclass
export default class LayerStory1 extends BaseDrag {
    public static instance: LayerStory1 = null;

    @property({ type: [cc.Node], tooltip: "人物剪影" })
    private shadows: cc.Node[] = [];
    @property({ type: [cc.Node], tooltip: "spine动画" })
    private skes: cc.Node[] = [];
    @property({ type: cc.Node, tooltip: "点击收集" })
    private clicks: cc.Node = null;

    @property({ type: cc.Node, tooltip: "icon根节点" })
    private icons: cc.Node = null;
    @property({ type: cc.Node, tooltip: "icon" })
    public icon: cc.Node = null;

    @property({ type: cc.Node, tooltip: "上划提示节点" })
    private huaTipSke: cc.Node = null;

    // 拖拽
    private dragNames: string[] = ['顾云泽(男主)', '刘琳(母亲)', '林倩(情人)', '顾远东(父亲)'];
    // 点击
    private clickNames: string[] = ['受伤的手', '卑鄙的林姨', '病重的顾母'];

    private dragType: EDragType = EDragType.Drag;
    private startId: number = 1;
    private isHuaTip: boolean = true;

    protected onLoad() {
        super.onLoad();
        LayerStory1.instance = this;

        this.rootScale = SceneGame.instance.getRootScale();

        this.showHuaTip();
        this.initShadowIcons();
    }

    private showHuaTip() {
        if (this.isHuaTip) {
            this.isHuaTip = false;
            this.huaTipSke.active = true;
        }
    }

    private hideHuaTip() {
        this.huaTipSke.active = false;
    }

    private initShadowIcons() {
        this.dragType = EDragType.Drag;
        this.icons.active = true;
        this.clicks.active = false;
        for (let i = 0; i < this.skes.length; i++) {
            const node = this.skes[i];
            node.active = false;
        }
        for (let i = 0; i < this.shadows.length; i++) {
            const node = cc.instantiate(this.icon);
            node.parent = this.icons;
            node.getComponent(ItemDrag).setData({ id: i + this.startId, index: i, type: EDragType.Drag, name: this.dragNames[i] });
        }
        this.icon.getComponent(ItemDrag).setData({ id: -1, index: -1, type: EDragType.Drag, name: "" });
    }

    private initClickIcons() {
        this.dragType = EDragType.Click;
        this.clicks.active = true;

        for (let i = this.icons.children.length - 1; i > -1; i--) {
            this.icons.children[i].destroy();
        }

        for (let i = 0; i < this.clicks.children.length; i++) {
            const node = cc.instantiate(this.icon);
            node.parent = this.icons;
            node.y = 0;
            const comp = node.getComponent(ItemDrag);
            comp.setData({ id: i + this.startId + 10, index: i, type: EDragType.Click, name: this.clickNames[i] });
        }
        SceneGame.instance.showGuideUI(this.clicks.children[0]);
    }

    private clicked: number[] = [-1, -1, -1];
    private getClickData(): { nodes: cc.Node[], callback: Function } {
        let data: { nodes: cc.Node[], callback: Function } = { nodes: null, callback: null };
        if (this.clicks.active) {
            let self = this;
            data.nodes = this.clicks.children;
            data.callback = async (node: cc.Node, index: number) => {
                const id = index + this.startId;
                if (this.clicked[index] > -1) {
                    return;
                }
                this.clicked[index] = 1;
                // 显示icon图片
                this.icons.children[index].getComponent(ItemDrag).showIcon(index);
                // 隐藏教学
                SceneGame.instance.hideGuideUI();
                
                // 点的时候
                switch (index) {
                    case 0:     // 点情人手
                        this.fuHaoAnim('fuhao_da');
                        await GameUtil.sleep(500);
                        this.fuHaoAnim('fuhao_idle_say');
                        break;
                    case 1:     // 点情人
                        this.qingRenAnim('qingren_say');
                        break;
                    case 2:     // 点顾母头
                        this.guYunZeAnim(ESkeNameType.GuIdle, true);
                        break;
                }
                // 气泡对话
                TalkModule.updateStoryBubble(id, this.talkComplete.bind(this));
            }
        } else {
            // 先判断在滑动区域内?
            const isInter = GameUtil.intersect(this.clickRect, this.icons);
            if (!isInter) return null;
            data.nodes = this.icons.children;
            data.callback = (node: cc.Node, index: number) => {
                // 设置点击数据
                this.touchData = {
                    id: node.getComponent(ItemDrag).getId(),
                    node: node,
                    isMove: false,
                }
            }
        }
        return data;
    }

    /** 对话完成回调 */
    private talkComplete(id: number) {
        switch(id) {
            case 1:     // 富豪说完
                this.fuHaoAnim('fuhao_idle2');
                break;
            case 2:     // 情人切待机动画
                this.qingRenAnim('qingren');
                // 富豪手拿离婚协议
                this.fuHaoAnim('fuhao_li');
                break;
            case 8:     // 富豪扔离婚协议书
                this.fuHaoAnim(ESkeNameType.FuHaoReng);
                break;
        }

        let isComplete = true;
        for (let id = 1; id < 4; id++) {   // 前情1
            const talk = TalkModule.getSayConfigById(id);
            if (!talk.isComplete) {
                isComplete = false;
                break;
            }
        }

        if (isComplete && this.dragType === EDragType.Click) {
            this.dragType = EDragType.Default;
            this.icons.active = false;
            this.icons.removeAllChildren();

            setTimeout(() => {
                // GlobalData.gameView = EGameType.Story1;
                // Message.instance.send(EventID.REFRESH_GAMEUI, { name: "医院转场" });
                SceneGame.instance.showLayer(ELayerType.LayerStory2);
            }, 1500);
        }
    }

    private startY: number;
    private touchData: { id: number, node: cc.Node, isMove: boolean } = { id: -1, node: null, isMove: false };
    public touchStart(event: cc.Event.EventTouch) {
        const pos = this.getClickPos(event);
        this.startY = pos.y;
        const data = this.getClickData();
        for (let i = 0; i < data?.nodes?.length; i++) {
            // TODO 需要先点情人和手才能点顾母头
            if (data.nodes[i] === this.clicks.children[2]) {
                if (this.clicked[0] <= -1 || this.clicked[1] <= -1) {
                    return;
                }
            }

            const intersect = GameUtil.intersect(this.clickRect, data.nodes[i]);
            if (intersect) {
                if (this.dragType === EDragType.Drag) {
                    const icon = cc.find("icon", data.nodes[i]);
                    if (icon?.active) {
                        data.callback && data.callback(data.nodes[i], i);
                        data.callback = null;
                    }
                } else {
                    data.callback && data.callback(data.nodes[i], i);
                    data.callback = null;
                }
            }
        }
    }

    public touchMove(event: cc.Event.EventTouch) {
        if (this.dragType !== EDragType.Drag) return;

        const pos = this.getClickPos(event);
        if (this.touchData.id > -1 && Math.abs(this.clickRect.y - this.startY) > 50) {
            this.touchData.isMove = true;
            this.setMoveIconPos();
        } else {
            if (!this.touchData.isMove) {
                // const x = this.contentPos.x + (nowPos.x - startPos.x);
                // this.content.getComponent(ScrollContent).set(this.iconRoot, x);
            } else {
                this.setMoveIconPos();
            }
        }
    }

    public touchEnd(event: cc.Event.EventTouch) {
        const index = this.touchData.id - 1;
        const shadow = this.shadows[index];
        const isInter = GameUtil.intersect(this.clickRect, shadow);
        if (isInter) {
            shadow.active = false;
            const idles = [ESkeNameType.GuIdle, ESkeNameType.GuMuIdle2, 'qingren', ESkeNameType.FuHaoIdle1];
            if (index === 0) {
                this.guYunZeAnim(idles[index]);
            } else if (index === 1) {
                AudioManager.instance.playSound("咳嗽声");
                this.guMuAnim(ESkeNameType.GuMuKeSou);
            } else if (index === 2) {
                this.qingRenAnim('qingren');
            } else if (index === 3) {
                this.fuHaoAnim(idles[index]);
            }
            this.destroyIcon();
        }

        // 重置
        this.icon.x = -1000;
        this.clickRect.x = -1000;
        this.touchData = { id: -1, node: null, isMove: false };

        setTimeout(() => {
            const isComplete = this.getIsComplete();
            if (isComplete && this.dragType === EDragType.Drag) {
                this.initClickIcons();
            }
        }, 1000 / 60);
    }

    private destroyIcon() {
        for (let i = 0; i < this.icons.children.length; i++) {
            const temp = this.icons.children[i];
            const touch = this.touchData.node;
            if (temp === touch) {
                // temp.destroy();
                cc.find("icon", touch).active = false;
            }
        }
        // 完成一个后隐藏提示
        this.hideHuaTip();
    }

    /** 顾云泽动画 */
    private guYunZeAnim(name: ESkeNameType | string, isSay: boolean = false) {
        const data: IBaseSkeData = {
            ske: this.skes[0].getComponent(sp.Skeleton),
            animName: name,
            isLoop: true,
        }
        data.ske.node.active = true;
        data.hideBones = ["顾嘴"]
        if (name === ESkeNameType.GuIdle) {
            if (isSay) {
                data.showBones = ["顾嘴"];
                setTimeout(() => {
                    const bone = data.ske.findBone("顾嘴");
                    if (bone) {
                        bone.active = false;
                    }
                }, 22 * 150);
            }
        } else if (name === ESkeNameType.GuAiDa) {
            data.timeScale = 2;
            data.isLoop = false;
            data.callback = () => {
                this.guYunZeAnim(ESkeNameType.GuIdle, false);
            }
        }
        GameUtil.playAnimation(data);
    }

    private keCount: number = 0;
    private guMuAnim(name: ESkeNameType | string) {
        const bone = this.skes[3].getComponent(sp.Skeleton).findBone("hand2");
        if (bone) {
            bone.active = false;
        }

        const data: IBaseSkeData = {
            ske: this.skes[3].getComponent(sp.Skeleton),
            animName: name,
            isLoop: true,
            // hideBones: ["hand2"],
        }

        data.ske.node.active = true;
        data.ske.node.scaleX = 1;
        if (name === ESkeNameType.GuMuKeSou) {
            this.keCount++;
            data.isLoop = false;
            data.callback = () => {
                if (this.keCount >= 2) {
                    this.guMuAnim(ESkeNameType.GuMuIdle2);
                } else {
                    this.guMuAnim(ESkeNameType.GuMuKeSou);
                }
            };
        } else if (name === ESkeNameType.GuMuKu2) {
            data.ske.node.scaleX = 1;
        }
        GameUtil.playAnimation(data);
    }

    private qingRenAnim(name: string) {
        const data: IBaseSkeData = {
            ske: this.skes[2].getComponent(sp.Skeleton),
            animName: name,
            isLoop: true,
        }
        data.ske.node.active = true;
        GameUtil.playAnimation(data);
    }

    private fuHaoAnim(name: ESkeNameType | string) {
        const data: IBaseSkeData = {
            ske: this.skes[1].getComponent(sp.Skeleton),
            animName: name,
            isLoop: true,
        }
        data.ske.node.active = true;
        if (name === 'fuhao_da') {
            AudioManager.instance.playSound("扇巴掌");
            data.isLoop = false;
            data.callback = () => {
                this.fuHaoAnim(ESkeNameType.FuHaoIdle1);
            }

            // 顾浩挨打延时0.3秒
            setTimeout(() => {
                let zIndexs = [1, 2, 3, 4];
                for (let i = 0; i < this.skes.length; i++) {
                    this.skes[i].zIndex = zIndexs[i];
                }
                this.guYunZeAnim(ESkeNameType.GuAiDa);
            }, 300);
        } else if (name === ESkeNameType.FuHaoReng) {
            // let zIndexs = [1, 3, 4, 2];
            // for (let i = 0; i < this.skes.length; i++) {
            //     this.skes[i].zIndex = zIndexs[i];
            // }

            data.isLoop = false;
            data.callback = () => {
                this.fuHaoAnim(ESkeNameType.FuHaoIdle2);
            }
            // 顾母手拿离婚协议
            setTimeout(() => {
                this.guMuAnim(ESkeNameType.GuMuKu2);
            }, 500);
        }
        GameUtil.playAnimation(data);
    }

    /** 设置拖动中的icon位置 */
    private setMoveIconPos() {
        this.icon.getComponent(ItemDrag).setData({ id: this.touchData.id, index: -1, type: EDragType.Drag, name: '' });
        this.icon.setPosition(cc.v2(this.clickRect.x, this.clickRect.y));
    }

    /**
     * 获取拖拽/点击全部完成?
     * @returns 
     */
    public getIsComplete() {
        if (this.dragType === EDragType.Drag) {
            let count = 0;
            for (let i = 0; i < this.icons.children.length; i++) {
                const node = this.icons.children[i];
                const icon = cc.find("icon", node);
                if (icon.active) {
                    count++;
                }
            }
            return count === 0;
        } else if (this.dragType === EDragType.Click) {
            const length = this.icons.children.length;
            const tempArr = this.clicked.filter((o) => o == 1);
            return tempArr.length === length;
        }
    }

    public getViewData() {
        return VIEW_DATA;
    }
}
AppService.instance.registViewData(VIEW_DATA);